📡 Connexion perdue — Système hors ligne. Vérifiez votre connexion internet.
{% with messages = get_flashed_messages(with_categories=true) %} {% for category, message in messages %}
{{ message }}
{% endfor %} {% endwith %} {% if session.get('user') %} {% set role = session.get('role','eleve') %} {% set prenom = session.get('prenom','U') %} {% set nom = session.get('nom','') %}
{# ══ PROFIL ══ #} {% if view == 'profil' %}
{{ prenom[0]|upper }}{{ nom[0]|upper if nom else '' }}

{{ prenom }} {{ nom }}

{{ session.get('user') }}

{{ role|capitalize }}
Email{{ session.get('user') }}
Rôle{{ role|capitalize }}
{% if role == 'eleve' %} {% set actifs_p = emprunts|selectattr('rendu','equalto',false)|list %}
Emprunts actifs{{ actifs_p|length }}
Total emprunts{{ emprunts|length }}
{% if mes_resa %}
Réservations{{ mes_resa|length }}
{% endif %} {% set tot = namespace(v=0) %}{% for e in actifs_p %}{% set tot.v = tot.v + e.amende %}{% endfor %} {% if tot.v > 0 %}
Amende{{ tot.v }}€
{% endif %} {% endif %}
{# Mot de passe + Changement #}

🔑 Mot de passe

{% if not mdp_clair %}

⚠ Mot de passe non mémorisé — changez-le ci-dessous pour l'activer.

{% endif %}
Changer de mot de passe
{% if mes_resa or mes_creneaux %}
Mes réservations & créneaux
{% for mat_id, cr in mes_creneaux.items() %}{% set m = materiel.get(mat_id) %}{% if m %}
{{ m.emoji }} {{ m.nom }}
📅 Créneau · Retrait : {{ cr.datetime }} · Casier : {{ cr.casier }}
{% endif %}{% endfor %} {% for mat_id, pos in mes_resa.items() %}{% set m = materiel.get(mat_id) %}{% if m %}
{{ m.emoji }} {{ m.nom }}
🔔 File d'attente — position n°{{ pos }}
{% endif %}{% endfor %} {% endif %} {# ══ PROFIL ÉLÈVE (resp/admin) ══ #} {% elif view == 'profil_eleve' %}
{{ user.prenom[0]|upper }}{{ user.nom[0]|upper if user.nom else '' }}

{{ user.prenom }} {{ user.nom }}

{% if user.email != session.get('user') and user.role != 'admin' %}
{% endif %}

{{ user.email }}

{{ user.role|capitalize }} {% if user.get('blacklist') %}Suspendu{% endif %}
Email{{ user.email }}
{% if role == 'admin' and user.get('mdp_clair') %}
Mot de passe (temp)
{{ user.mdp_clair }} (cliquer pour révéler)
{% endif %}
Total emprunts{{ emprunts|length }}
{% set actifs_e = emprunts|selectattr('rendu','equalto',false)|list %}
Actifs{{ actifs_e|length }}
{% set tot2 = namespace(v=0) %}{% for e in actifs_e %}{% set tot2.v = tot2.v + e.amende %}{% endfor %} {% if tot2.v > 0 %}
Amende{{ tot2.v }}€
{% endif %}
{% if role in ['admin','responsable'] %}
{% if role == 'admin' %}
{% if user.get('blacklist') %} {% else %}{% endif %}
{% endif %}
{% endif %} {% if emprunts %}
Historique
{% for e in emprunts %}
{{ e.get('mat_emoji','📦') }} {{ e.mat_nom }}
{{ e.date_debut }} → {{ e.date_retour }}
{% if e.rendu %}Terminé{% elif e.statut=='en_retard' %}En retard{% else %}En cours{% endif %}
{% if e.amende > 0 %}
Amende{% if e.get('amende_payee') %} (payée){% endif %}{{ e.amende }}€
{% endif %} {% if e.note_retour %}
📝 {{ e.note_retour }}
{% endif %}
{% endfor %} {% endif %} {# ══ INVENTAIRE ══ #} {% elif view == 'dashboard' %} {# Emprunt actif #} {% if mon_emprunt_actif %}{% set e = mon_emprunt_actif %}
{{ e.get('mat_emoji','📦') }}
{% if e.statut=='en_attente_verification' %}Retour en vérification{% elif e.statut=='en_retard' %}Emprunt en retard{% else %}Emprunt en cours{% endif %}
{{ e.mat_nom }}
Code : {{ e.code_unique }} · Casier : {{ e.casier }} · {% if e.statut=='en_retard' %}{{ e.amende }}€ d'amende{% elif e.statut=='en_attente_verification' %}En attente de validation{% else %}Retour le {{ e.date_retour }}{% endif %}
{% if e.statut=='en_retard' and e.amende > 0 and not e.get('amende_payee') %}💳 Payer {{ e.amende }}€{% endif %}
Voir →
{% endif %} {# Hint cliquable #} {% set nb_actifs = mes_emprunts_actifs|length if mes_emprunts_actifs is defined else 0 %} {% if nb_actifs >= 3 %}
⚠️ Vous avez déjà {{ nb_actifs }} emprunt{% if nb_actifs > 1 %}s{% endif %} actif{% if nb_actifs > 1 %}s{% endif %} — maximum 3. Rendez du matériel avant d'emprunter à nouveau.
{% elif nb_actifs > 0 %}
👆 Cliquez sur une carte · {{ 3 - nb_actifs }} emprunt{% if 3 - nb_actifs > 1 %}s{% endif %} restant{% if 3 - nb_actifs > 1 %}s{% endif %}
{% else %}
👆 Cliquez sur une carte pour voir les détails et emprunter ou réserver le matériel
{% endif %} {# Catalogue 2 catégories #} {% for cat_nom in ['Informatique', 'Scolaire'] %} {% set items_cat = [] %} {% for m_id, m in items.items() %}{% if m.get('categorie','') == cat_nom %}{% set _ = items_cat.append((m_id, m)) %}{% endif %}{% endfor %} {% if items_cat %}
{% if cat_nom == 'Informatique' %}💻{% else %}📚{% endif %} {{ cat_nom }} {{ items_cat|length }} article{% if items_cat|length > 1 %}s{% endif %}
{% for m_id, m in items_cat %}
{{ m.emoji }}
{% if m.dispo %}Disponible {% else %}Emprunté{% endif %} {% if m.est_reserve_par_moi %}Réservé n°{{ m.ma_position }}{% endif %}
{{ m.nom }}
{# Stock indicator #} {% set qtot = m.get('quantite', 1) %} {% set stk = m.get('stock', 1 if m.dispo else 0) %} {% if qtot > 1 %}
{{ stk }}/{{ qtot }} dispo
{% endif %} {% if not m.dispo and m.get('date_retour_prevu') %}
📅 Dispo le {{ m.date_retour_prevu }}
{% endif %} {% if m.get('nb_resa',0) > 0 %}
🔔 {{ m.nb_resa }} en file d'attente
{% endif %}
{# MODAL FICHE #}
{{ m.emoji }}

{{ m.nom }}

{% if m.dispo %}Disponible {% else %}Emprunté{% endif %} {{ m.etat }} {{ m.get('categorie','') }}
{% if m.get('description') %}
Description

{{ m.description }}

{% endif %}
Informations
État{{ m.etat }}
Durée max{{ m.get('duree_max','7') }} jours
{% if not m.dispo and m.get('date_retour_prevu') %}
Retour prévu{{ m.date_retour_prevu }}
{% endif %} {% if m.get('nb_resa',0) > 0 %}
File d'attente{{ m.nb_resa }} personne{% if m.nb_resa > 1 %}s{% endif %}
{% endif %}
{# ── DISPONIBLE ── #} {% if m.dispo %}
Ce matériel est disponible — remplissez les dates ci-dessous et confirmez !
⚠️ Retard : 1 €/jour automatiquement · Prolongement possible une fois (+1 jour) · Un email de confirmation vous sera envoyé
{% elif not m.dispo %} {% if m.get('date_retour_prevu') %}
🕐 Ce matériel est actuellement emprunté — retour prévu le {{ m.date_retour_prevu }}
{% else %}
🔴 Ce matériel n'est pas disponible pour le moment
{% endif %}

Vous avez deux options : réserver un créneau pour une date précise, ou recevoir un email dès qu'il est rendu.

{% if not m.mon_creneau %}
A
Réserver pour une date précise (créneau)
📌 Le matériel sera réservé pour vous à la date choisie
{% else %}
📅
✅ Créneau réservé !
Retrait : {{ m.mon_creneau.datetime }} · Casier : {{ m.mon_creneau.casier }}
{% endif %}
ou
{% if not m.est_reserve_par_moi %}
B
Être prévenu par email dès qu'il est rendu

📧 Vous recevrez un email automatique dès que l'élève rend le matériel

{% else %}
🔔 Vous êtes en file d'attente — position n°{{ m.ma_position }}
Un email vous sera envoyé automatiquement dès que le matériel est rendu.
{% endif %} {% endif %}
{% endfor %}
{% endif %} {% endfor %} {# ══ REÇU ══ #} {% elif view == 'recu' %}

Emprunt confirmé

{{ e.id }}

Élève{{ e.user_name }}
Matériel{{ e.get('mat_emoji','') }} {{ e.mat_nom }}
Début{{ e.date_debut }}
Casier{{ e.casier }}
À rendre le{{ e.date_retour }}
Code de retrait
{{ e.code_unique }}
À présenter au responsable
📧 Email de confirmation envoyé · Retard : 1 €/jour · Prolongement +1 jour possible une fois
{# ══ PAGE PAIEMENT ══ #} {% elif view == 'paiement' %}
{# Header #}
← Retour
{# Récap commande #}
Récapitulatif
Amende de retard {{ emp.mat_nom }}
Référence{{ emp.id }}
Date limite dépassée{{ emp.date_retour }}
Total à régler {{ emp.amende }}€
🔒 Paiement simulé — aucune vraie transaction
{# Formulaire carte #}
Informations de paiement
{# ── Choix du type de carte ── #}
▬▬
•••• •••• •••• ••••
PRÉNOM NOM MM/AA
VISA
💳
{# ══ REÇU CRÉNEAU ══ #} {% elif view == 'recu_creneau' %}
📅

Réservation confirmée !

{{ cr.mat_nom }}

Matériel{{ cr.mat_emoji }} {{ cr.mat_nom }}
Casier{{ cr.casier }}
Date de retrait{{ cr.datetime }}
À rendre le{{ cr.date_retour }}
Code de réservation
{{ cr.code }}
À présenter au responsable lors du retrait
📅 Présentez-vous au casier {{ cr.casier }} à l'heure réservée
{# ══ HISTORIQUE ══ #} {% elif view == 'historique' %} {% if mes_creneaux_hist %}
📅 Créneaux réservés
{% for mat_id, cr in mes_creneaux_hist.items() %}{% set m = materiel.get(mat_id) %}
{{ cr.mat_emoji }}
{{ cr.mat_nom }}
Code : {{ cr.code }} · Casier : {{ cr.casier }}
Retrait : {{ cr.datetime }} · Retour prévu : {{ cr.date_retour }}
📅 Créneau
{% endfor %} {% endif %} {# Amendes en attente de paiement — card rapide #} {% set amendes_actives = emprunts|selectattr('rendu','equalto',true)|selectattr('amende_payee','equalto',false)|list %} {% for e in amendes_actives %}{% if e.amende > 0 %}
Amende à régler
{{ e.mat_nom }}
{{ e.amende }} €
Retard constaté · Réglez votre amende en ligne.
💳 Payer {{ e.amende }}€
{% endif %}{% endfor %} {% if emprunts %} {% for e in emprunts %}
{{ e.get('mat_emoji','📦') }}
{{ e.mat_nom }}
{{ e.id }} · Code : {{ e.code_unique }} · Casier : {{ e.casier }}
{{ e.date_debut }} → {{ e.date_retour }}{% if e.date_prolonge %} +1j prolongé{% endif %}
{% if e.rendu %}Terminé {% elif e.statut=='en_attente_verification' %}En vérification {% elif e.statut=='en_retard' %}En retard {% else %}En cours{% endif %} {% if not e.rendu and e.statut != 'en_attente_verification' %} {% set h = e.heures_restantes %}{% if h is not none %} {% if h < 0 %}
💸 {{ e.amende }}€ (+1€/j)
{% if not e.get('amende_payee') %}💳 Payer{% endif %} {% elif e.get('total_minutes_restantes', 9999) <= 60 %}
⚠ {{ e.get('total_minutes_restantes', 0) }} min restante{% if e.get('total_minutes_restantes',0) > 1 %}s{% endif %}
{% elif h <= 2 %}
⚠ {{ h }}h {{ e.get('minutes_restantes',0) }}min restantes
{% elif h <= 24 %}
⚠ {{ h }}h restantes
{% else %}
{{ h }}h restantes
{% endif %} {% endif %}{% endif %} {% if e.amende > 0 and e.rendu %}
{{ e.amende }}€ {% if e.get('amende_payee') %}payée{% else %}à régler{% endif %}
{% endif %}
{% if not e.rendu and e.statut != 'en_attente_verification' %}
{% if not e.date_prolonge %} {% else %} 🔒 Prolongement utilisé {% endif %}
{# Panneau code casier — indépendant, s'ouvre sous les boutons #} {% elif e.statut == 'en_attente_verification' %}
⏳ Retour déclaré — en attente d'inspection par le responsable
{% endif %} {% if not e.rendu and not e.date_prolonge and e.statut != 'en_attente_verification' %} {% endif %} {% if e.note_retour %}
📝 Note : {{ e.note_retour }}
{% endif %}
{% endfor %} {% else %}
📭

Aucun emprunt pour le moment.

Parcourir l'inventaire →
{% endif %} {# ══ RESP EMPRUNTS ══ #} {% elif view == 'resp_emprunts' %} {# ── CASIER OUVERT (retour de ouvrir_casier_resp ou direct) ── #} {% if casier_ouvert %}
🔓
Casier déverrouillé — {{ casier_ouvert.casier }}
{{ casier_ouvert.user_name }} · {{ casier_ouvert.mat_nom }}
Code d'ouverture
{{ casier_ouvert.code_unique }}
{% endif %} {# ── CASIER OUVERT DIRECT ── #} {% if casier_ouvert_direct %}
🔓
Casier {{ casier_ouvert_direct.casier }}
{% if casier_ouvert_direct.emp %}
Emprunté par {{ casier_ouvert_direct.emp.user_name }} · {{ casier_ouvert_direct.emp.mat_nom }}
{% elif casier_ouvert_direct.mat %}
{{ casier_ouvert_direct.mat.emoji }} {{ casier_ouvert_direct.mat.nom }} — Libre
{% endif %}
{% if casier_ouvert_direct.emp %}
Code d'ouverture
{{ casier_ouvert_direct.emp.code_unique }}
{% else %}
Aucun emprunt actif sur ce casier
{% endif %}
{% endif %} {# ── NOTIFICATION RETOURS EN ATTENTE ── #} {% if en_attente_retour %}
📬 {{ en_attente_retour|length }} retour{% if en_attente_retour|length > 1 %}s{% endif %} à inspecter — {{ en_attente_retour|map(attribute='mat_nom')|join(', ') }}
{% endif %} {# ── FILES D'ATTENTE — cadre cliquable ── #} {% if resa_info %} {% set total_resa = namespace(n=0) %}{% for q in resa_info.values() %}{% set total_resa.n = total_resa.n + q|length %}{% endfor %}
🔔
{{ resa_info|length }} matériel{% if resa_info|length > 1 %}s{% endif %} en file d'attente
{{ total_resa.n }} élève{% if total_resa.n > 1 %}s{% endif %} en attente — cliquez pour voir
{% endif %} {# ── STATS ── #}
{{ actifs|length }}
Actifs
{{ actifs|selectattr('statut','equalto','en_retard')|list|length }}
En retard
{{ en_attente_retour|length }}
À vérifier
{{ actifs|map(attribute='amende')|sum }}€
Amendes
{# ── TABLEAU EMPRUNTS ACTIFS ── #} {% if actifs %}
{% for e in actifs %} {% if e.get('en_attente_retour') %} {% endif %} {% endfor %}
ÉlèveMatérielCasierRetour prévuAmendeStatutActions
{{ e.user_name }}
{{ e.user_email }}
{{ e.get('mat_emoji','') }} {{ e.mat_nom }} {{ e.casier }} {{ e.date_retour }} {% if e.amende > 0 %}{{ e.amende }}€{% if e.get('amende_payee') %} ✓{% endif %}{% else %}—{% endif %} {% if e.statut=='en_attente_verification' %}À vérifier {% elif e.statut=='en_retard' %}En retard {% else %}En cours{% endif %} {% if e.get('en_attente_retour') %}
{% else %} {% endif %}
{% else %}

Aucun emprunt actif.

{% endif %} {# ══ MATÉRIEL ══ #} {% elif view == 'resp_materiel' %}

➕ Ajouter du matériel

💡 L'emoji est détecté automatiquement · Le statut du casier est mis à jour automatiquement.

🔑 Ouvrir un casier

{% set casiers_list = materiel.values()|map(attribute='casier')|list|sort|unique|list %} {% for casier in casiers_list %} {% set mat_casier = materiel.values()|selectattr('casier','equalto',casier)|first %} {% set emp_casier = none %} {% for e in actifs if e.casier == casier and not e.rendu %}{% set emp_casier = e %}{% endfor %} {{ casier }} {{ mat_casier.emoji if mat_casier else '📦' }} {% if mat_casier and not mat_casier.dispo %}🔴{% else %}🟢{% endif %} {% endfor %}
{% for m_id, m in materiel.items() %}{% endfor %}
MatérielCatégorieCasierÉtatStatutFile d'attenteAction
{{ m.emoji }} {{ m.nom }} {{ m.get('categorie','—') }} {{ m.casier }} {{ m.etat }} {% if m.dispo %}🟢 Disponible{% else %}🔴 Emprunté{% endif %} {% if m_id in resa_info and resa_info[m_id] %}{{ resa_info[m_id]|length }} pers.{% else %}{% endif %} {% if m.dispo %}
{% else %}{% endif %}
{# ══ UTILISATEURS ══ #} {% elif view == 'admin_users' %}

👤 Créer un compte

{% for u in users %}{% endfor %}
NomEmailRôleEmpruntsAmendeStatutActions
{{ u.prenom }} {{ u.nom }} {{ u.email }} {% if u.role=='admin' %}Admin{% elif u.role=='responsable' %}Resp.{% else %}Élève{% endif %} {{ u.get('nb_emprunts',0) }} {% if u.get('amende_tot',0) > 0 %}{{ u.amende_tot }}€{% else %}—{% endif %} {% if u.get('blacklist') %}Suspendu{% else %}Actif{% endif %} {% if u.email != session.get('user') and u.role != 'admin' %}
{% else %}—{% endif %}
{# ══ LOGS ══ #} {% elif view == 'admin_logs' %}
{% if logs %}{% for log in logs %}
{{ log.datetime }}{{ log.action }}{{ log.detail }}{{ log.user }}
{% endfor %}{% else %}
📭

Aucune activité.

{% endif %}
{# ══ ADMIN SYSTEM ══ #} {% elif view == 'admin_system' %}
{{ stats.actifs }}
Actifs
{{ stats.en_retard }}
En retard
{{ stats.en_attente_retour }}
À vérifier
{{ stats.amendes_actives }}€
Amendes
{{ stats.nb_users }}
Utilisateurs
{{ stats.termines }}
Terminés
Activité récente
{% if logs %}{% for log in logs[:15] %}
{{ log.datetime }}{{ log.action }}{{ log.detail }}
{% endfor %}{% else %}
📭

Aucune activité.

{% endif %}
{# ══ MESSAGES ══ #} {% elif view == 'messages' %} {% if role in ['responsable','admin'] %}
{% if role == 'responsable' %} {% endif %}
{# Formulaire → élève (ou admin voit juste ce formulaire) #}

✉️ {% if role=='admin' %}Nouveau message{% else %}Message à un élève{% endif %}

{% if role == 'responsable' %} {# Formulaire → admin (signalement) #} {% endif %} {% endif %} {# Liste des messages #} {% if messages %}
Conversations ({{ messages|length }})
{% for msg in messages %}
{{ msg.de_nom[0]|upper }}
{{ msg.sujet }} {% if not msg.lu and msg.a == session.get('user') %}Nouveau{% endif %} {% if msg.replies %}{{ msg.replies|length }} réponse{% if msg.replies|length > 1 %}s{% endif %}{% endif %}
De : {{ msg.de_nom }}{{ msg.a_nom }} · {{ msg.date }}
{% endfor %} {% else %}
💬

Aucun message pour le moment.

{% endif %} {% endif %}
{# ══ AUTH ══ #} {% else %} 🌐 enes-atmac.be ↗
LoanTrack
INRACI · Gestion d'emprunts

Bon retour

Connectez-vous à votre compte

ou
Mot de passe oublié ?

Pas de compte ? S'inscrire

Créer un compte

Rejoignez LoanTrack INRACI

Déjà inscrit ? Se connecter

Mot de passe oublié

Un nouveau mot de passe vous sera envoyé par email.

← Retour à la connexion

{% endif %}